package com.ease.kernel {

	import com.ease.util.collections.MapProvider;

	import flash.utils.getQualifiedClassName;

	import mx.collections.ArrayCollection;

	public class Kernel
	{
		private static var defaultInstance:Kernel;

		private static var instances:MapProvider =new MapProvider();

		private var services:MapProvider = new MapProvider();

		private var filters:MapProvider = new MapProvider();

		public function Kernel(priv:Private)
		{
		}

		/**
		 * 获取KernelManager实例，当参数domain为null时返回defaultInstance
		 * @param domain 不同特例的实现
		 *
		 */
		public static function getInstance(domain:Object = null):Kernel
		{
			if(null == domain)
			{
				if(defaultInstance == null){
					defaultInstance = new Kernel(new Private());
				}
				return defaultInstance;
			}

			domain = getKeyName(domain);//构造key值

			var value:Object = instances.getObject(domain);
			if(value == null)
			{
				var instance:Kernel = new Kernel(new Private());
				instances.put(domain,instance);
				return instance;
			}
			else
			{
				return value as Kernel;
			}
		}

		/**
		 *
		 * 获取与某特定实例及上下文环境的Service
		 * <br>含有过滤功能
		 *
		 */
		public function getService(key:Object = null,context:Object = null,priority:uint = 0):Object
		{
			var list:ArrayCollection = getArrayCollectionInstance(this.services,key);
			list = doFilte(list,key,context);
			if(list != null && list.length > 0)
			{
				var index:uint = 0;
				for(var i:uint;i<list.length;i++){
					var object:Object = list.getItemAt(i);
					if(!(object is IPriority) || (object as IPriority).priority < priority){
						index = (i == 0) ? i : (i - 1);
						break;
					}
				}
				return list.getItemAt(index);
			}
			return null;
		}

		/**
		 * 获取与某特定实例及上下文环境的Service组合
		 * <br>含有过滤功能
		 *
		 */
		public function getServices(key:Object=null,context:Object = null):ArrayCollection
		{
			var list:ArrayCollection = getArrayCollectionInstance(this.services,key);
			list = doFilte(list,key,context);
			if(list != null)
			{
				return new ArrayCollection(list.source.concat());
			}
			return new ArrayCollection();
		}


		public function registerService(service:Object,key:Object = null):void
		{
			if(service == null){
				return;
			}
			var list:ArrayCollection = getArrayCollectionInstance(this.services,key);
			if(list != null){
				registerWithPriority(list,service);

			}
		}

		/**
		 *
		 * 注册过程中增加优先级处理
		 *
		 *
		 */
		private function registerWithPriority(list:ArrayCollection,service:Object):void
		{
			if(!(service is IPriority) || (service as IPriority).priority == 0){
				list.addItem(service);
				return;
			}

			var servicePriority:uint = (service as IPriority).priority;
			var index:uint = 0;
			for(var i:uint;i<list.length;i++){
				var object:Object = list.getItemAt(i);
				if(!(object is IPriority) || (object as IPriority).priority < servicePriority){
					index = i;
					break;
				}
			}
			list.addItemAt(service,index);//按照优先级插入
		}

		public function registerServiceFilter(filter:IFilter, key:Object = null):void
		{
			if(filter == null)
			{
				return;
			}
			var list:ArrayCollection = getArrayCollectionInstance(this.filters,key);
			if(list != null){
				list.addItem(filter);
			}
		}

		public function getServiceFilters(key:Object = null):Array
		{
			var list:ArrayCollection = getArrayCollectionInstance(this.filters,key);
			if(list != null)
			{
				return list.source.concat();
			}
			return [];
		}

		public function clearFilters(key:Object = null):Array
		{
			var list:ArrayCollection = getArrayCollectionInstance(this.filters,key);
			if(list != null && list.length > 0)
			{
				var result:Array = list.source.concat();
				list.removeAll();
				return result;//返回被清空的过滤器集合
			}
			return [];
		}

		/**
		 * 这里使用对象的类的签名，如果直接传入String类型则视为类签名
		 *
		 *
		 */
		private static function getKeyName(value:Object):String
		{
			if(value is String){
				return value as String;
			}else{
				return getQualifiedClassName(value);
			}
		}

		private function getArrayCollectionInstance(provider:MapProvider,key:Object):ArrayCollection
		{
			if(key == null)
			{
				key = new Object();
			}
			key = getKeyName(key);
			var value:Object = provider.getObject(key);
			if(null == value)
			{
				var list:ArrayCollection = new ArrayCollection();
				provider.put(key,list);
				return list;
			}
			else
			{
				if(value is ArrayCollection){
					return value as ArrayCollection;
				}
			}
			return new ArrayCollection();
		}

		/**
		 * 过滤service集合
		 *
		 *
		 */
		private function doFilte(serviceList:ArrayCollection ,value:Object = null,context:Object = null):ArrayCollection
		{
			if(serviceList == null || serviceList.length <= 0)
			{
				return serviceList;//集合没有元素不过滤
			}
			var filterList:ArrayCollection = getArrayCollectionInstance(this.filters,value);
			if(filterList.length > 0)
			{
				var result:ArrayCollection = new ArrayCollection;
				for each(var service:Object in serviceList)
				{
					var flag:Boolean = true;
					for each(var filter:IFilter in filterList)
					{
						if(!filter.doFilte(service,value,context))
						{
							flag = false;
							break;
						}
					}
					if(flag){
						result.addItem(service);
					}
				}
				return result;
			}
			return serviceList;
		}

	}
}
class Private{}
